#ifndef EPOLL_H
#define EPOLL_H
extern "C" {
#include <sys/epoll.h>
}
#include <vector>
#include <tuple>

# define EPOLL_MAX_EVENTS 1024 //  一般在编译时就能确定该机器上最合适的MAX_EVENTS，所以此处直接定义为宏，且代码中不再更改

class socket;

class epoll
{
public:
    class event : protected epoll_event
    {
    public:
        event(struct epoll_event&& ev={0, {0}}):epoll_event(ev){};
        inline int fileno()const { return data.fd; }
        inline int mask()const { return events; }
    private:
    };

    epoll(int size=1024);
    epoll(const epoll&)=delete;
    epoll(epoll&&);
    virtual~epoll();

    inline operator int()const { return fd; }
    inline int fileno()const { return int(*this); }

    void mount(int fd, int event_mask);
    void umount(int fd);
    void modify(int fd, int event_mask);
    std::tuple<size_t,event*> poll(int timeout_msec=-1);

    static epoll fromfd(int &&fd);
    inline uint32_t default_mask()const {
        return  EPOLL_EVENTS::EPOLLIN | EPOLL_EVENTS::EPOLLOUT | EPOLL_EVENTS::EPOLLERR | EPOLL_EVENTS::EPOLLRDHUP;
    }

    //  convenience function
    void mount(const class socket& sock, int event_mask);
    void umount(const class socket& sock);
    void modify(const class socket& sock, int event_mask);

private:
    int fd;
    event events[EPOLL_MAX_EVENTS];
    struct epoll_event ev;
};

#endif // EPOLL_H
